home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / vga16.c < prev    next >
C/C++ Source or Header  |  1995-02-26  |  5KB  |  282 lines

  1. /*
  2.  * VGA 16 colour mode support routines
  3.  *
  4.  * Copyright (C) Evan Harris, 1993, 1994, 1995.
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <vga.h>
  13. #include "vga16.h"
  14.  
  15. #define FONT_WIDTH 8
  16. #define FONT_LINES 16
  17.  
  18.  
  19. #ifndef USEGETPIXEL
  20. static unsigned char *vga16mem = NULL;
  21. static int vga16width, vga16height;
  22. #endif
  23. static unsigned char *vga16workmem =  NULL;
  24. static char *font_bits;
  25.  
  26.  
  27. /*
  28.  * To be called after vga_setmode()
  29.  */
  30.  
  31. int
  32. vga16_init()
  33. {
  34.     vga_modeinfo *mode;
  35.     FILE *f;
  36.     int nelem;
  37.  
  38.     mode = vga_getmodeinfo(vga_getcurrentmode());
  39.     if (mode->colors != 16) {
  40.     return -1;
  41.     }
  42. #ifndef USEGETPIXEL
  43.     if (vga16mem != NULL) {
  44.     free(vga16mem);
  45.     }
  46.     vga16mem = calloc(mode->width * mode->height / 2, sizeof(unsigned char));
  47. #endif
  48.     vga16workmem = malloc(mode->width * sizeof(unsigned char));
  49.     nelem = ((FONT_WIDTH + 7) / 8) * FONT_LINES * 256;
  50.     font_bits = malloc(nelem * sizeof(char));
  51. #ifndef USEGETPIXEL
  52.     if (vga16mem == NULL || vga16workmem == NULL || font_bits == NULL) {
  53.     return -1;
  54.     }
  55.  
  56.     vga16width = mode->width;
  57.     vga16height = mode->height;
  58. #else
  59.     if (vga16workmem == NULL || font_bits == NULL) {
  60.     return -1;
  61.     }
  62. #endif    
  63.     
  64.     f = fopen(VGA16FONT, "r");
  65.     if (f == NULL) {
  66.     fprintf(stderr, "Cannot find '%s'\n", VGA16FONT);
  67.     exit(1);
  68.     }
  69.     if (fread(font_bits, sizeof(char), nelem, f) != nelem) {
  70.     fprintf(stderr, "Font reading failed - read error.\n");
  71.     }
  72.     fclose(f);
  73.  
  74.     return 0;
  75. }
  76.  
  77.  
  78. #ifndef USEGETPIXEL
  79. void
  80. vga16_drawscansegment(unsigned char *colors, int x, int y, int length)
  81. {
  82.     unsigned char *p, *c;
  83.     int l, changed;
  84.     
  85.     p = &vga16mem[(y * vga16width + x) >> 1];
  86.     c = colors;
  87.     l = length;
  88.     changed = 0;
  89.     while (l > 0) {
  90.     if (*p != (*c << 4 | *(c + 1))) {
  91.         *p = *c << 4 | *(c + 1);
  92.         changed = 1;
  93.     }
  94.     p++;
  95.     c += 2;
  96.     l -= 2;
  97.     }
  98.  
  99.     if (changed) {
  100.     vga_drawscansegment(colors, x, y, length);
  101.     }
  102. }
  103.  
  104.  
  105. void
  106. vga16_drawscanline(int y, unsigned char *colors)
  107. {
  108.     vga16_drawscansegment(colors, 0, y, vga16width);
  109. }
  110. #endif
  111.  
  112.  
  113. static void
  114. vga16_putchar(int x, int y, char c, int fg, int bg)
  115. {
  116.     int i, j, mask, colour;
  117. #ifndef USEGETPIXEL
  118.     int vp;
  119. #endif
  120.  
  121.     y -= FONT_LINES - 1;
  122.     for (i = FONT_LINES * c; i < FONT_LINES * (c + 1); i++) {
  123.     mask = 0x80;
  124.     for (j = x; j < x + 8; j++) {
  125.         if (font_bits[i] & mask) {
  126.         colour = fg;
  127.         } else {
  128.         colour = bg;
  129.         }
  130.         
  131. #ifndef USEGETPIXEL
  132.         vp = (y * vga16width + j) / 2;
  133.  
  134.         if (j & 1) {
  135.         if ((vga16mem[vp] & 0x0f) != colour) {
  136.             vga16mem[vp] = (vga16mem[vp] & 0xf0) | colour;
  137.             vga_setcolor(colour);
  138.             vga_drawpixel(j, y);
  139.         }
  140.         } else {
  141.         if ((vga16mem[vp] >> 4) != colour) {
  142.             vga16mem[vp] = (colour << 4) | (vga16mem[vp] & 0x0f);
  143.             vga_setcolor(colour);
  144.             vga_drawpixel(j, y);
  145.         }
  146.         }
  147. #else
  148.         vga_setcolor(colour);
  149.         vga_drawpixel(j, y);
  150. #endif        
  151.  
  152.         mask = mask >> 1;
  153.     }
  154.     y++;
  155.     }
  156. }
  157.  
  158.  
  159. void
  160. vga16_text(int x, int y, char *s, int fg, int bg)
  161. {
  162.     int startx = x;
  163.  
  164.     while (*s != '\0') {
  165.     switch (*s) {
  166.       case '\n':
  167.         y += FONT_LINES;
  168.         x = startx;
  169.         break;
  170.       case '\b':
  171.         x -= FONT_WIDTH;
  172.         break;
  173.       default:
  174.         vga16_putchar(x, y, *s, fg, bg);
  175.         x += FONT_WIDTH;
  176.         break;
  177.     }
  178.     s++;
  179.     }
  180. }
  181.  
  182.  
  183. void
  184. vga16_setpixel(int color, int x, int y)
  185. {
  186. #ifndef USEGETPIXEL
  187.     unsigned char *vp = &vga16mem[(y * vga16width + x) >> 1];
  188.  
  189.     if (x & 1) {
  190.     if ((*vp & 0x0f) == color) {
  191.         return;
  192.     }
  193.     *vp = (*vp & 0xf0) | color;
  194.     } else {
  195.     if ((*vp >> 4) == color) {
  196.         return;
  197.     }
  198.     *vp = (color << 4) | (*vp & 0x0f);
  199.     }
  200. #endif
  201.     
  202.     vga_setcolor(color);
  203.     vga_drawpixel(x, y);
  204. }
  205.  
  206.  
  207. #ifndef USEGETPIXEL
  208. int
  209. vga16_getpixel(int x, int y)
  210. {
  211.     unsigned char *vp = &vga16mem[(y * vga16width + x) >> 1];
  212.  
  213.     if (x & 1) {
  214.     return *vp & 0x0f;
  215.     } else {
  216.     return *vp >> 4;
  217.     }
  218. }
  219. #endif
  220.  
  221.  
  222. /*
  223.  * This assumes that (x0 % 8 == 0) and (x1 % 8 == 7) due to
  224.  * vga_drawscansegment()
  225.  */
  226.  
  227. void
  228. vga16_filledblock(int x0, int y0, int x1, int y1, int color)
  229. {
  230.     int x, y;
  231. #ifndef USEGETPIXEL
  232.     unsigned char *vp;
  233.     int c;
  234. #endif
  235.  
  236.     for (x = 0; x <= x1 - x0; x++) {
  237.     vga16workmem[x] = color;
  238.     }
  239.  
  240.     for (y = y0; y <= y1; y++) {
  241. #ifndef USEGETPIXEL
  242.     x = x0;
  243.     c = (color << 4) | color;
  244.     vp = &vga16mem[(y * vga16width + x) >> 1];
  245.     if (x & 1) {
  246.         *vp++ = (*vp & 0xf0) | color;
  247.         x++;
  248.     }
  249.     while (x <= x1 - 1) {
  250.         *vp++ = c;
  251.         x += 2;
  252.     }
  253.     if (x < x1) {
  254.         *vp++ = (*vp & 0x0f) | (color << 4);
  255.     }
  256. #endif    
  257.     vga_drawscansegment(vga16workmem, x0, y, x1 - x0 + 1);
  258.     }
  259. }
  260.  
  261.  
  262. void
  263. vga16_redrawscreen()
  264. {
  265. #ifndef USEGETPIXEL
  266.     unsigned char *vp, *vw;
  267.     int x, y;
  268.     
  269.     for (y = 0; y < vga16height; y++) {
  270.     vp = &vga16mem[(y * vga16width) >> 1];
  271.     vw = vga16workmem;
  272.  
  273.     for (x = 0; x < vga16width / 2; x++) {
  274.         *vw++ = (*vp & 0xf0) >> 4;
  275.         *vw++ = *vp++ & 0x0f;
  276.     }
  277.  
  278.     vga_drawscansegment(vga16workmem, 0, y, vga16width);
  279.     }
  280. #endif
  281. }
  282.